#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/un.h>

#define N 128

// 01-socket 192.168.1.2  8000
// argv[0]   arv[1]       argv[2]
int main(int argc, char const *argv[])
{

    int sockfd, ret, newsockfd;
    struct sockaddr_un myaddr, client_addr;
    socklen_t addrlen;
    char buf[N] = {0};

    remove(argv[1]); // mysocket文件存在就删除

    if (argc != 2)
    {
        fprintf(stderr, "错误:运行程序时请带入参数(./18-tcp_unix_server ip port)\n");
        exit(-1);
    }

    // 创建一个socket 用于本地进程间通讯
    sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("socket");
        exit(-1);
    }

    printf("sockfd=%d\n", sockfd);

    memset(&myaddr, 0, sizeof(myaddr));           // 清空结构体
    memset(&client_addr, 0, sizeof(client_addr)); // 清空结构体
    myaddr.sun_family = AF_UNIX;                  // 什么类型的通信
    strcpy(myaddr.sun_path, argv[1]);

    ret = bind(sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr));
    if (ret < 0)
    {
        perror("bind");
        exit(-1);
    }

    ret = listen(sockfd, 10);
    if (ret < 0)
    {
        perror("listen");
        exit(-1);
    }

    // system("netstat -ant");
    addrlen = sizeof(client_addr); //这个赋值如果缺少, 可能会引发程序错误

    while (1)
    {
        newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &addrlen); // 接收客户端tcp连接请求
        if (newsockfd < 0)
        {
            perror("accept");
            exit(-1);
        }

        printf("newsockfd=%d\n", newsockfd);

        while (1)
        {
            ret = recv(newsockfd, buf, N, 0); // 接收客户端发来的数据
            if (ret < 0)
            {
                perror("read");
                exit(-1);
            }

            if (strncmp(buf, "quit", 4) == 0)
                break;

            printf("buf= %s\n", buf);

            printf(">:");
            fgets(buf, N, stdin);
            buf[strlen(buf) - 1] = 0; // 清除'\n'

            ret = send(newsockfd, buf, N, 0); // 发送给客户端
            if (ret < 0)
            {
                perror("send");
                exit(-1);
            }
        }

        close(newsockfd); // 关闭客户端连接
    }

    close(sockfd);

    return 0;
}